/**
 * @p.md
 * 
 * ActorSystem 是 Actor 系统的核心
 */
import { ProcessRegistry, IProcessRegistry } from './processRegistry';
import { EventStream, EventStreams, Events } from './eventStream';
import { RootContext } from './rootContext';
import { PID } from './pid';
import { ActorMetrics } from '../metrics/actorMetrics';
import { Props } from './props';

/**
 * Remote系统接口（简化版，用于类型定义）
 */
export interface RemoteSystem {
  isStarted(): boolean;
  sendRemoteMessage(pid: PID, message: any): void;
  activatorForAddress(address: string): any;
}

/**
 * ActorSystem 类是 Actor 系统的核心，管理所有 Actor
 */
export class ActorSystem {
  /**
   * 进程注册表
   */
  readonly processRegistry: IProcessRegistry;
  
  /**
   * 事件流
   */
  readonly eventStream: EventStream;
  
  /**
   * 根上下文
   */
  readonly root: RootContext;
  
  /**
   * 死信观察者
   */
  readonly deadLetterWatcher: PID;
  
  /**
   * 监控指标
   */
  readonly metrics: ActorMetrics;
  
  /**
   * 远程系统，用于处理远程Actor通信
   * 在启动远程系统后由Remote组件设置
   */
  private _remote?: RemoteSystem;
  
  /**
   * 创建一个新的 ActorSystem
   */
  constructor() {
    // 初始化 ProcessRegistry
    ProcessRegistry.initialize(this);
    this.processRegistry = ProcessRegistry.getInstance();
    
    // 创建和初始化其他组件
    this.eventStream = EventStreams.createEventStream(this);
    this.metrics = new ActorMetrics(this);
    
    // 创建根上下文
    this.root = new RootContext(this);
    
    // 创建一个临时的 PID 作为死信观察者
    this.deadLetterWatcher = new PID(this.processRegistry.address(), "deadLetterWatcher");
    
    // 订阅系统事件
    this.subscribeToDiagnostics();
    
    // 输出系统初始化信息
    console.log(`[SYSTEM] ActorSystem 已初始化, 地址: ${this.processRegistry.address()}`);
  }
  
  /**
   * 获取远程系统
   */
  get remote(): RemoteSystem | undefined {
    return this._remote;
  }
  
  /**
   * 设置远程系统
   * @param remote 远程系统实例
   */
  setRemote(remote: RemoteSystem): void {
    console.log(`[SYSTEM] 设置Remote系统`);
    this._remote = remote;
  }
  
  /**
   * 检查PID是否为远程PID
   * @param pid 要检查的PID
   */
  isRemotePID(pid: PID): boolean {
    if (!pid) return false;
    return pid.address !== 'local' && pid.address !== this.processRegistry.address();
  }
  
  /**
   * 尝试将消息路由到远程PID
   * @param pid 目标PID
   * @param message 消息
   * @returns 是否成功路由
   */
  tryRouteRemoteMessage(pid: PID, message: any): boolean {
    if (!this.isRemotePID(pid)) return false;
    
    if (this._remote && this._remote.isStarted()) {
      try {
        console.log(`[SYSTEM] 通过Remote路由消息到: ${pid.toString()}`);
        this._remote.sendRemoteMessage(pid, message);
        return true;
      } catch (error) {
        console.error(`[SYSTEM] 远程消息路由失败:`, error);
        return false;
      }
    }
    
    console.warn(`[SYSTEM] 尝试发送远程消息但Remote系统未启动: ${pid.toString()}`);
    return false;
  }
  
  /**
   * 终止 Actor 系统
   */
  async terminate(): Promise<void> {
    console.log(`[SYSTEM] 正在终止ActorSystem...`);
    
    // 关闭所有活动的Actor
    // TODO: 实现 Actor 清理
    
    // 关闭远程系统
    if (this._remote) {
      console.log(`[SYSTEM] 关闭Remote系统`);
      // TODO: 调用 Remote 系统的关闭方法
    }
    
    // 清理事件流
    this.eventStream.publish(new Events.SystemShutdown());
    
    console.log(`[SYSTEM] ActorSystem 已终止`);
  }
  
  /**
   * 订阅系统诊断事件
   */
  private subscribeToDiagnostics(): void {
    // 订阅死信事件
    this.eventStream.subscribe(Events.DeadLetter, (msg: Events.DeadLetter) => {
      console.warn(`[SYSTEM] 无效信件: 发送到 ${msg.pid.toString()}, 消息类型: ${typeof msg.message}`);
    });
  }
}